#include <boost/foreach.hpp>
#include "mapped_file.h++"
#include "word_tree.h++"
#include "serializer.h++"
#include "latin1sucks.h++"

void print_bytes(const std::string bytes) {
	BOOST_FOREACH(char byte, bytes) {
		unsigned char ubyte = static_cast<unsigned char>(byte);
		std::cout << std::hex << static_cast<int>(ubyte) << ' ';
	}
	std::cout << std::dec;
}

int main(int argc, char* argv[]) {
	

	ReadOnlyMappedMemory nodefile("TRIE.INDEX");
	ReadOnlyMappedMemory elsefile("INFO.INDEX");
	ReadOnlyMappedMemory postingsfile("POSTINGS.INDEX");
	
	WordTree::NodeHeader& root = nodefile.get_header(
			).get_object_after<WordTree::NodeHeader>();

	bool verbose = false;
	for (int i = 1; i < argc; ++i) {
		if (std::string(argv[i]) == "--debug") {
			verbose = true;
			continue;
		}
		std::cout << "converting ";
		print_bytes(argv[i]);
		std::cout << "'" << argv[i] <<"'to latin1 : ";
		std::string yuck = UTF8ToBrokenLatin1(std::string(argv[i]));
		print_bytes(yuck);
		std::cout << "'" << yuck << "', trying to reconvert :  ";
		std::string aaahh_better = Latin1toUTF8(yuck.c_str());
		print_bytes(aaahh_better);
		std::cout << "'" << aaahh_better << "'" << std::endl;


	 	std::cout << "word " << argv[i] << ' ';
		WordTree::NodeHeader* node = root.getWord(nodefile, yuck);
		if (!node) {
			std::cout << "not found." << std::endl;
			continue;
		}
		PointerTo<DetailedDataHeader> detail_ptr = node->get_detailed_data();
		if (verbose)
			std::cout << "(detail_ptr is " << detail_ptr.pointer.address << ')';
		if (!detail_ptr.pointer.address) {
			std::cout << "is only a prefix."
				<< std::endl;
			continue;
		}
		DetailedDataHeader& detailed = elsefile.get(detail_ptr);
		std::cout << "found in " << detailed.nb_docs << " documents :"
			<< std::endl;

		DetailedDataHeader::document_table_type doctable(
				detailed.getDocumentTable());
		DetailedDataHeader::tfidf_table_type tfidftable(
				detailed.getTFIDFTable());
		DetailedDataHeader::posting_table_type postingtable(
				detailed.getPostingTable());

		for (size_t i = 0; i < detailed.nb_docs; ++i) {
			PointerTo<Document> d(*doctable.getElement(i));
			MemoryMappedFloat tfidf(*tfidftable.getElement(i));
			PointerTo<PostingData> postingsptr(*postingtable.getElement(i));
			if (verbose) {
				std::cout << "(doc pointer is " << d.pointer.address << ',';
				std::cout << "postingptr is " << postingsptr.pointer.address << ')';
			}
			PostingData& postings(postingsfile.get(postingsptr));
			Document& doc = elsefile.get(d);
			std::cout << '\t' << doc.get_path_string(elsefile)
				<< " : " << tfidf.value << " ("
				<< postings.nb_occurences << " occurences :";
			for (size_t p = 0; p < postings.nb_occurences; ++p) {
				std::cout << *postings.getPostingTable(
						).getElement(p)
					<< "["
					<< *postings.getOffsetTable(
						).getElement(p) << "] ";
			}
			std::cout << std::endl;
		}
	}
	
	return 0;
}
